﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sstream>
#include <cstring>
using namespace std;

// 优化算法
//class Solution {
//public:
//    bool canPartition(vector<int>& nums) {
//        int n = nums.size();
//        int sum = 0;
//        for (int i = 0; i < n; i++) sum += nums[i];
//        if (sum % 2 != 0) return false;
//        vector<bool> dp(sum / 2 + 1);
//
//        dp[0] = true;
//
//        for (int i = 1; i <= n; i++)
//        {
//            for (int j = sum / 2; j >= 1; j--)
//            {
//                if (j >= nums[i - 1]) dp[j] = dp[j] || dp[j - nums[i - 1]];
//            }
//        }
//        return dp[sum / 2];
//    }
//};


//#include <iostream>
//#include <cstdio>
//#include <cstdlib>
//#include <unistd.h>
//#include <cstring>
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <fcntl.h>
//#include <sys/select.h>
//
//using namespace std;
//
//int main(int argc, char* argv[])
//{
//    int fd = open("text.txt", O_RDONLY);
//    if (fd < 0)
//    {
//        perror("read error");
//        return -1;
//    }
//    // 更新最大文件描述符，因为标准输入为0，所以新创建的描述符肯定是最大的
//    int maxfd = fd;
//    while (1)
//    {
//        // 处理文件描述符集合rdfs
//        fd_set rdfs;
//        FD_ZERO(&rdfs);
//        FD_SET(0, &rdfs);
//        FD_SET(fd, &rdfs);
//        // 调用select进行监听
//        struct timeval timeout;
//        timeout.tv_sec = 5;
//        timeout.tv_usec = 100;
//        if (select(maxfd + 1, &rdfs, NULL, NULL, &timeout) < 0)
//        {
//            perror("select error");
//            exit(-1);
//        }
//        // 判断哪个文件描述符准备好，并处理准备好的文件描述符
//        if (FD_ISSET(0, &rdfs))
//        {
//            char buffer[1024] = { 0 };
//            fgets(buffer, 1024, stdin);
//            cout << "recv from stdin(0): " << buffer << endl;
//        }
//        if (FD_ISSET(fd, &rdfs))
//        {
//            char buffer[1024] = { 0 };
//            ssize_t ret = read(fd, buffer, sizeof(buffer));
//            if (ret < 0)
//            {
//                perror("read error");
//                exit(-1);
//            }
//            printf("recv from fd(%d): %s\n", fd, buffer);
//        }
//        sleep(4);
//    }
//    return 0;
//}


//#pragma once                                                                                                          
//#include <vector>
//#include <unistd.h>
//#include <sys/select.h>
//#include "server.hpp"
//#include "InetAddr.hpp"
//
//namespace SelectServer
//{
//    class selectserver
//    {
//    public:
//        selectserver(int port) : _port(port), fds_arry(1024, -1)
//        {   }
//
//        // 初始化select服务器    
//        void InitServer()
//        {
//            _listensock = TcpSocket::server::Socket();
//            TcpSocket::server::Bind(_listensock, _port);
//            TcpSocket::server::Listen(_listensock);
//        }
//
//        // select服务器运行
//        void Run()
//        {
//            fds_arry[0] = _listensock;
//            while (true)
//            {
//                fd_set readfds;
//                FD_ZERO(&readfds);
//                struct timeval time = { 10, 5000 };
//                // time也可以用下面进行初始化
//                /*time.tv_sec = 5;
//                time.tv_usec = 100;*/
//                int max_fd = 0;
//
//                // 将read_arry数组中的文件描述符设置进程fds_arry位图中
//                for (int i = 0; i < 1024; i++)
//                {
//                    if (fds_arry[i] != -1)
//                    {
//                        FD_SET(fds_arry[i], &readfds);
//                        if (max_fd < fds_arry[i]) max_fd = fds_arry[i];
//                    }
//                }
//
//                // 调用select对readfds中的文件描述符进行等待数据
//                switch (select(max_fd + 1, &readfds, NULL, NULL, &time))
//                {
//                case 0:
//                    // 没有一个文件描述符的读事件就绪
//                    cout << "select timeout" << endl;
//                    break;
//                case -1:
//                    // select失败
//                    cout << "select error" << endl;
//                default:
//                    // 有读事件发生
//                    Soluation(readfds);
//                    break;
//                }
//            }
//        }
//
//        // 处理已就绪的读事件
//        void Soluation(fd_set& readfds)
//        {
//            for (int i = 0; i < fds_arry.size(); i++)
//            {
//                if (FD_ISSET(fds_arry[i], &readfds))
//                {
//                    if (fds_arry[i] == _listensock)
//                    {
//                        // 有新链接到来
//                        struct sockaddr_in peer;
//                        socklen_t len;
//                        int sockfd = accept(_listensock, (struct sockaddr*)&peer, &len); // 注意：accept不会阻塞，因为文件描述符已经就绪了
//
//                        // 将新链接设置进readfds_arry数组中
//                        InetAddr clientaddr(peer);
//                        printf("Get a new Link, sockfd: %d, client addr %s:%d\n", sockfd, clientaddr.Ip(), clientaddr.Port());
//                        AddfdsArry(sockfd);
//                    }
//                    else
//                    {
//                        //其他事件就绪
//                        char buffer[1024];
//                        int n = recv(fds_arry[i], &buffer, sizeof(buffer) - 1, 0);
//                        switch (n)
//                        {
//                        case -1:
//                            // 读取失败
//                            cout << fds_arry[i] << " :recv error" << endl;
//                            close(fds_arry[i]);
//                            fds_arry[i] = -1;
//                            break;
//                        case 0:
//                            // 对端关闭
//                            cout << fds_arry[i] << " :is closed" << endl;
//                            close(fds_arry[i]);
//                            fds_arry[i] = -1;
//                            break;
//                        default:
//                            // 正常接收对端信息
//                            buffer[n] = '\0';
//                            printf("[client: %d]# %s", fds_arry[i], buffer);
//                            break;
//                        }
//                    }
//                }
//            }
//        }
//
//        // 将新的sockfd添加到辅助数组中
//        void AddfdsArry(int sockfd)
//        {
//            int pos = 0;
//            while (pos < fds_arry.size())
//            {
//                if (fds_arry[pos] == -1)
//                {
//                    fds_arry[pos] = sockfd;
//                    printf("%d add to select array!\n", sockfd);
//                    break;
//                }
//                pos++;
//            }
//            if (pos == fds_arry.size())
//            {
//                close(sockfd);
//                cout << "selectserver is full" << endl;
//            }
//        }
//    private:
//        int _listensock; // 监听套接字    
//        int _port;  // 端口号  
//        vector<int> fds_arry;  // 存放读事件的文件描述符
//    };
//}